package com.matrix.async.core;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.log4j.Logger;

public class WorkThread implements Runnable, APPComponent, Controllable {
	private Logger log = Logger.getLogger(WorkThread.class);
	// 初始化
	static final int INIT = 0;
	// 运行中
	public static final int RUNNING = 1;
	// 终止
	static final int SHUTDOWN = 2;
	// 暂停
	static final int SUSPEND = 3;
	// 结束
	static final int TERMINATED = 4;

	protected final ReentrantLock lock = new ReentrantLock();
	protected final Condition condition = lock.newCondition();
	protected final ReentrantLock runLock = new ReentrantLock();

	protected String name = null;
	protected String taskType = null;
	protected Thread thread = null;
	// 启动延时
	protected int startupDelay = 0;

	protected volatile int runState = 0;
	protected volatile boolean switchOn = true;
	// 是否启用开关
	protected String beanUse = "true";

	public String getBeanUse() {
		return beanUse;
	}

	public void setBeanUse(String beanUse) {
		this.beanUse = beanUse;
	}

	protected void work() {
	};

	@Override
	public void run() {
		log.info("工作线程run");
		while (runState != SHUTDOWN) {
			final ReentrantLock lock = this.lock;
			lock.lock();
			try {
				try {
					while (runState == SUSPEND) {
						log.info("工作线程等待");
						condition.wait();
					}
				} catch (InterruptedException e) {
					thread.interrupt();
				}
			} finally {
				lock.unlock();
			}
			work();
		}
		runState = TERMINATED;
	}

	public void setSwitchOn(boolean switchOn) {
		final ReentrantLock lock = this.lock;
		lock.lock();
		try {
			this.switchOn = switchOn;
		} finally {
			lock.unlock();
		}
	}

	public void setStartupDelay(int startupDelay) {
		this.startupDelay = startupDelay;
	}

	public boolean isActive() {
		return runLock.isLocked();
	}

	public boolean isTerminated() {
		return runState == TERMINATED;
	}

	@Override
	public void start() {
		final ReentrantLock lock = this.lock;
		lock.lock();
		try {
			if (switchOn && (runState == INIT || runState == TERMINATED)) {
				thread.start();
				runState = RUNNING;
			}
		} finally {
			lock.unlock();
		}
	}

	@Override
	public void suspend() {
		final ReentrantLock lock = this.lock;
		lock.lock();
		try {
			if (switchOn && runState == RUNNING) {
				runState = SUSPEND;
			}
		} finally {
			lock.unlock();
		}

	}

	@Override
	public void resume() {
		final ReentrantLock lock = this.lock;
		lock.lock();
		try {
			if (switchOn && runState == SUSPEND) {
				runState = RUNNING;
				log.info("WorkThread[" + thread.getName() + "] resume");
				condition.signalAll();
			}
		} finally {
			lock.unlock();
		}

	}

	@Override
	public void shutdownNow() {
		final ReentrantLock lock = this.lock;
		lock.lock();
		try {
			if (switchOn && runState != TERMINATED) {
				runState = SHUTDOWN;
				log.info("WorkThread[" + thread.getName() + "] shutdownNow");
				thread.interrupt();
			}
		} finally {
			lock.unlock();
		}
	}

	@Override
	public void shutdown() {
		final ReentrantLock lock = this.lock;
		lock.lock();
		try {
			if (switchOn && runState != TERMINATED) {
				runState = SHUTDOWN;
				log.info("WorkThread[" + thread.getName() + "] shutdown");
			}
		} finally {
			lock.unlock();
		}

	}

	public static ThreadFactory defaultThreadFactory() {
		return new DefaultThreadFactory();
	}

	public int getStartupDelay() {
		return startupDelay;
	}

	@Override
	public String getName() {
		return name;
	}

	@Override
	public String getTaskType() {
		return taskType;
	}

	public int getRunState() {
		return runState;
	}

	public void setRunState(int runState) {
		this.runState = runState;
	}

}
